#include "util.h"
#include "table.h"
#include <stdlib.h>

/*
 * TYPE_DECL: INT, FLOAT, CHAR
 * ADDITIVE_OP: PLUS, MINUS
 * MULTIPLI_OP: TIMES, SLASH
 * RELATION_OP: LSS, LEQ, GTR, GEQ, NEQ, DEQ
 */

Bool isTYPE_DECL(TokenType tt)
{
    if (tt == INT || tt == FLOAT || tt == CHAR)
        return TRUE;
    else
        return FALSE;
}

Bool token_type_match(TokenType ta, TokenType tb)
{
    // char = '<x>'
    if ((ta == INT && tb == C_INT) ||
        (ta == FLOAT && tb == C_FLOAT) ||
        (ta == CHAR && tb == C_CHAR)) {
            return TRUE;
    }
    else {
        return FALSE;
    }
}

Bool isADDITIVE_OP(TokenType tt)
{
    if (tt == PLUS || tt == MINUS)
        return TRUE;
    else
        return FALSE;
}

Bool isMULTIPLI_OP(TokenType tt)
{
    if (tt == TIMES || tt == SLASH)
        return TRUE;
    else
        return FALSE;
}

Bool isRELATION_OP(TokenType tt)
{
    if (tt == LSS || tt == LEQ ||
        tt == GTR || tt == GEQ ||
        tt == NEQ || tt == DEQ)
        return TRUE;
    else
        return FALSE;
}

Value str_to_value(TokenType tt, char *tb)
{
    Value ret;
    if (tt == INT || tt == C_INT) {
        ret.int_val = atoi(tb);
    }
    else if (tt == FLOAT || tt == C_FLOAT) {
        ret.float_val = (float)atof(tb);
    }
    else if (tt == CHAR || tt == C_CHAR) {
        ret.char_val = tb[0];
    }
    return ret;
}

//Type get_type(TokenType tt)
//{
//    switch (tt) {
//        case INT:
//            return T_INT;
//        case FLOAT:
//            return T_FLOAT;
//        case CHAR:
//            return T_CHAR;
//        default:
//            return T_VOID;
//    }
//}

Bool is_global_normal_element(Class clss)
{
    if (clss == GLOBAL_VAR || clss == GLOBAL_CONST) {
        return TRUE;
    }
    return FALSE;
}

Bool is_constant(Class clss)
{
    if (clss == GLOBAL_CONST || clss == LOCAL_CONST)
        return TRUE;
    return FALSE;
}

Opcode tt2oc(TokenType tt)
{
    if (tt >= LSS && tt <= DEQ) {
        return (IFLT_OP + tt - LSS);
    }
    else if (tt >= PLUS && tt <= SLASH){
        return (ADD_OP + tt - PLUS);
    }
}

Type tt2tp(TokenType tt)
{
    if (tt >= INT && tt <= CHAR) {
        return (T_INT + tt - INT);
    }
    else {
        return T_VOID;
    }
}

Bool isJumpOp(Opcode oc)
{
    if ((oc >= IFLT_OP && oc <= IFEQ_OP) ||
        oc == JMP_OP) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}

/*
typedef enum Opcode {
    ADD_OP = F_OPCODE, MINUS_OP, MUL_OP, DIV_OP,
    //LSS, LEQ, GTR, GEQ, NEQ, DEQ,
    IFLT_OP, IF_LET_OP, IFMT_OP, IFMET_OP,
    IFNE_OP, IFEQ_OP, FUNC_OP,
    ASSIGN_OP, JMP_OP, PARA_OP, CALL_OP, SCANF_OP, PRINTF_OP, 
    RETV_OP, RETN_OP,
} Opcode;
*/
Bool isAriOp(Opcode oc)
{
    if (oc >= ADD_OP && oc <= DIV_OP) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}

Bool isIfOp(Opcode oc)
{
    if (oc >= IFLT_OP && oc <= IFEQ_OP) {
        return TRUE;
    }
    else {
        return FALSE;
    }
}